package com.cuiweiyou.vigilesmicrecord.util;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Handler;
import android.os.Message;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Created by macpro on 2018/4/19.
 */

public class PlayUtil {
    private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;   // 采样精度，一个采样点16比特，相当于2个字节。
    private final int channelConfig = AudioFormat.CHANNEL_IN_STEREO;  // CHANNEL_IN_STEREO双声道，CHANNEL_IN_MONO单声道
    private final int sampleRateInHz = 16000;                         // 采样率。
    private final int bufferSize = AudioTrack.getMinBufferSize(
            sampleRateInHz,
            channelConfig,
            audioFormat);

    private AudioTrack audioTrack;
    private static PlayUtil instance;

    private boolean isPlaying = false;
    private Handler volumeHandler;
    private Handler playHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (1 == msg.what) {
                isPlaying = true;
            } else {
                isPlaying = false;
            }
        }
    };
    private PlayRunnable playRunnable;

    private PlayUtil() {
        audioTrack = new AudioTrack(
                AudioManager.STREAM_MUSIC,
                sampleRateInHz,
                channelConfig,
                audioFormat,
                bufferSize * 2,
                AudioTrack.MODE_STREAM);
    }

    public static PlayUtil getInstance() {
        if (null == instance) {
            synchronized (PlayUtil.class) {
                if (null == instance) {
                    instance = new PlayUtil();
                }
            }
        }
        return instance;
    }

    public void setVolumeHandler(Handler handler) {
        this.volumeHandler = handler;
    }

    public void startPlay(String wavPath) {
        if(isPlaying()){
            stopPlay();
        }

        playRunnable = new PlayRunnable(wavPath, playHandler);
        new Thread(playRunnable).start();
    }

    /**
     * 停止播放
     */
    public void stopPlay() {
        if (null != playRunnable) {
            playRunnable.stop();
        }
        playRunnable = null;
    }

    public boolean isPlaying() {
        return isPlaying;
    }

    public void release() {
        stopPlay();
        audioTrack.release();
    }

    /**
     * 播放线程
     */
    class PlayRunnable implements Runnable {

        private String wavPath;
        private Handler handler;
        private boolean playAble = true;

        public PlayRunnable(String path, Handler playHandler) {
            this.wavPath = path;
            this.handler = playHandler;
        }

        public void stop() {
            playAble = false;
        }

        @Override
        public void run() {
            if (null != volumeHandler) {
                Message msg = volumeHandler.obtainMessage();
                msg.obj = -1d;
                volumeHandler.sendMessage(msg);
            }

            Message emptyMsg = handler.obtainMessage();
            emptyMsg.what = 1;
            handler.sendMessage(emptyMsg);

            DataInputStream dis = null;
            try {
                FileInputStream in = new FileInputStream(wavPath);
                // in.skip(200);
                dis = new DataInputStream(in);

                byte[] tempBuffer = new byte[bufferSize];
                int readCount = 0;
                while (playAble && dis.available() > 0) {
                    readCount = dis.read(tempBuffer);

                    if (readCount != 0 && readCount != -1) {
                        long v = 0;
                        for (int i = 0; i < tempBuffer.length; i++) {
                            v += tempBuffer[i] * tempBuffer[i];
                        }
                        double mean = v / (double) readCount;
                        double volume = 10 * Math.log10(mean);

                        if (null != volumeHandler) {
                            Message msg = volumeHandler.obtainMessage();
                            msg.obj = volume;
                            volumeHandler.sendMessage(msg);
                        }

                        audioTrack.play();
                        audioTrack.write(tempBuffer, 0, readCount);
                    }
                }

                audioTrack.stop();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != dis) {
                        dis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            emptyMsg = handler.obtainMessage();
            emptyMsg.what = 0;
            handler.sendMessage(emptyMsg);
        }
    }
}


